home *** CD-ROM | disk | FTP | other *** search
- struct RIFF {
- char rID[4];
- DWORD rLen;
- } riff;
-
- struct FORMAT {
- char fID[4];
- DWORD fLen;
- WORD wTag;
- WORD wChannel;
- DWORD nSample;
- DWORD nByte;
- WORD align;
- WORD sample;
- };
-
- struct DATA {
- char dID[4];
- DWORD dLen;
- };
-
- struct WAVE {
- char wID[4];
- struct FORMAT fmt;
- struct DATA data;
- } wave;
-
- char error[80]; // description of error, if any
-
- int abortflag;
-
- // Watch the cancel button
- #pragma argsused
- BOOL CALLBACK StatusDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
- {
- if (msg==WM_INITDIALOG) {
- SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
- CenterWindow(hdlg);
- }
- if (msg==WM_COMMAND && wp==IDCANCEL) abortflag=1;
- return 0;
- }
-
- // Write out a block of sound data, do some processing if necessary.
- // Return 0:failure, otherwise: bytes written.
- WORD wavwrite(signed int *sample,WORD len,FILE *f)
- {
- if (hz44) {
- if (stereo) { // 44khz stereo: no processing needed
- if (fwrite(sample,len,1,f)==1) return len;
- }
- else { // 44khz mono: calculate left/right channel average, then write
- WORD nsamples;
- signed int *src=sample,*dst=sample;
- nsamples=len>>2;
- while (nsamples--) {
- *dst=(WORD)(((DWORD)*src+*(src+1))>>1);
- src+=2;
- dst++;
- }
- if (fwrite(sample,len>>1,1,f)==1) return len>>1;
- }
- }
- else {
- if (stereo) { // 22khz stereo: condense samples (write only samples 0, 2, 4 etc)
- WORD nsamples;
- DWORD *src=(DWORD *)sample,*dst=(DWORD *)sample;
- nsamples=len>>3;
- while (nsamples--) {
- *dst=*src; dst++; src+=2;
- }
- if (fwrite(sample,len>>1,1,f)==1) return len>>1;
- }
- else {
- if (bit16) {// 22khz mono 16bits
- WORD nsamples;
- signed int *src=sample,*dst=sample;
- nsamples=len>>3;
- while (nsamples--) {
- *dst=(WORD)(((DWORD)*src+*(src+1))>>1);
- src+=4;
- dst++;
- }
- if (fwrite(sample,len>>2,1,f)==1) return len>>2;
- }
- else { // 22 khz mono 8 bits
- WORD nsamples;
- signed int *src=sample;
- signed char *dst=sample;
- nsamples=len>>3;
- while (nsamples--) {
- *dst=128+HIBYTE((WORD)(((DWORD)*src+*(src+1))>>1));
- src+=4;
- dst++;
- }
- if (fwrite(sample,len>>3,1,f)==1) return len>>3;
- }
- }
- }
- return 0;
- }
-
- int record(char *image,DWORD startloc,DWORD size)
- {
- int first_time,i,bps;
- WORD offset,synch_size,written;
- DWORD end_pos,loc=startloc;
- FILE *f;
- HWND status;
- MSG msg;
-
- // Put up a modal dialog box (for status)
- abortflag=0;
- status=CreateDialog(hinst,"StatusDlg",0,StatusDlgProc);
- if (!status) {
- strcpy(error,"Cant create status window");
- return 0;
- }
- strcpy(error,"");
-
- // Create WAV file
- f=fopen(image,"wb");
- if (!f) {
- strcpy(error,"cant create file");
- return 0;
- }
-
- // Prepare RIFF+WAV header
- bps=1; // bytes per sample - for a 8 bit mono sample
- if (bit16) bps<<=1; // two times as much for 16 bit samples
- if (stereo) bps<<=1; // another 2x as much for stereo
- strcpy(riff.rID, "RIFF");
- riff.rLen = FRAME_SIZE * (DWORD)size + sizeof(struct WAVE);
- strcpy(wave.wID, "WAVE");
- strcpy(wave.fmt.fID, "fmt ");
- wave.fmt.fLen = sizeof(struct FORMAT) - 8;
- wave.fmt.wTag = 1;
- wave.fmt.wChannel = stereo?2:1; // nr of channels
- wave.fmt.nSample = hz44?44100L:22050L; // sample rate
- wave.fmt.nByte = (hz44?44100L:22050L) * bps; // avg dataspeed bytes/sec
- wave.fmt.align = bps; // size of one sample, in bytes
- wave.fmt.sample = bit16?16:8; // bits per sample
- strcpy(wave.data.dID, "data");
- wave.data.dLen = FRAME_SIZE * (DWORD)size;
-
- if (fwrite(&riff,sizeof(struct RIFF),1,f)!=1) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
- if (fwrite(&wave,sizeof(struct WAVE),1,f)!=1) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
-
- // Read the data in blocks, first in memory
- // loc: start position (sierra sector)
- // size: number of sectors to read
- // end_loc: sector number at where to end
- wave.data.dLen = 0L;
- first_time = 1;
- end_pos = loc+size;
- while (loc<end_pos) {
- // Check abort
- if (abortflag) {
- strcpy(error," Recording cancelled ");
- goto Errorexit;
- }
- // Update reading status
- sprintf(s,"sector %ld / %ld",loc-startloc,size);
- SetDlgItemText(status,STATUS,s);
- // Read data in buffers
- for (i=0;i<nbuf;i++) {
- //TODO: Fix bugs with the last sector(s)
- /*res=*/ ReadLong(loc,NBLOCK,bufseg[i]);
- loc+=NBLOCK;
- }
- /*
- if (res!=0x0100) {
- sprintf(error,"cant read raw sector, status %04x",res);
- goto Errorexit;
- }
- */
- // Except for first recording, synchronize data to previous data
- if (first_time == 0) {
- offset = 0;
- synch_size = SYNCH_SIZE;
- while (offset == 0) {
- for (i=(NBLOCK/4)*FRAME_SIZE;i<(((WORD)NBLOCK*FRAME_SIZE)-synch_size);i+=4) {
- if (memcmp(pprev_end+(NBLOCK/2)*FRAME_SIZE,pbuf[0]+i,synch_size) == 0) {
- if (offset==0)
- offset=i;
- else {
- synch_size *= 2;
- if (synch_size>4096) {
- strcpy(error,"Synchronisation failed. Retry the operation. Close some other programs, if possible.");
- goto Errorexit;
- }
- offset=0;
- break;
- }
- }
- }
- if (offset==0) {
- strcpy(error,"Synchronisation failed, no matching block. Retry the operation. Close some other programs, if possible.");
- goto Errorexit;
- }
- }
- }
- else
- offset = 0;
-
- first_time=0;
- memcpy(pprev_end,pbuf[nbuf-1],(WORD)((DWORD)FRAME_SIZE*NBLOCK));
-
- // Write all buffers to disk, except the last buffer
- for (i=0;i<nbuf-1;i++) {
- written=wavwrite((signed int *)(pbuf[i]+offset),((DWORD)FRAME_SIZE*NBLOCK)-offset,f);
- if (!written) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
- wave.data.dLen+=written;
- offset=0;
- }
- sprintf(s,"%s %ld Kbytes",Sector2MSF(loc-startloc),wave.data.dLen/1024);
- SetDlgItemText(status,STATUSDISK,s);
-
- // Write only half of last buffer, The next loop, after synchronisation the rest will be written
- written=wavwrite((signed int *)pbuf[nbuf-1],(DWORD)FRAME_SIZE*(NBLOCK/2),f);
- if (!written) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
- wave.data.dLen+=written;
-
- loc-=NBLOCK;
-
- // Give some time slices
- while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- // Fix WAV header
- fseek(f,0L,SEEK_SET);
- riff.rLen = wave.data.dLen + sizeof(struct WAVE);
- if (fwrite(&riff,sizeof(struct RIFF),1,f)!=1) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
- if (fwrite(&wave,sizeof(struct WAVE),1,f)!=1) {
- strcpy(error,"cant write to file (disk full?)");
- goto Errorexit;
- }
-
- fclose(f);
- DestroyWindow(status);
- return 1;
- Errorexit:
- if (f) fclose(f);
- unlink(image);
- DestroyWindow(status);
- return 0;
- }
-